package com.codemonkey.lq.extend.easyui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.codemonkey.lq.common.builder.Builders;
import com.codemonkey.lq.common.builder.MapBuilder;

/**
 * EasyUI Tree Node
 * @author LQ
 *
 */
public final class EasyUITreeNode {

	/*
		每个节点都具备以下属性：
		
		id：节点ID，对加载远程数据很重要。
		text：显示节点文本。
		iconCls: 标图样式的class
		state：节点状态，'open' 或 'closed'，默认：'open'。如果为'closed'的时候，将不自动展开该节点。
		checked：表示该节点是否被选中。
		attributes: 被添加到节点的自定义属性。
		children: 一个节点数组声明了若干节点。 
	 */

	private String id;
	private String text;
	private String iconCls;
	private String state = "open";
	private boolean checked;
	private Map<String, Object> attributes;
	private List<EasyUITreeNode> children;

	private EasyUITreeNode() {

	}

	public String getId() {
		return id;
	}

	public String getText() {
		return text;
	}

	public String getIconCls() {
		return iconCls;
	}

	public String getState() {
		return state;
	}

	public boolean isChecked() {
		return checked;
	}

	public Map<String, Object> getAttributes() {
		return attributes;
	}

	public Object getAttribute(String attributeKey) {
		return attributes.get(attributeKey);
	}

	public List<EasyUITreeNode> getChildren() {
		return children;
	}

	public void addChild(EasyUITreeNode child) {
		children.add(child);
	}

	/**
	 * 因为项目中大量使用Map类型, 所以提供了这个方法
	 * @return
	 */
	public Map<String, Object> toMap() {

		final MapBuilder<Object> builder = Builders.newMapBuilder().append("id", id).append("text",
				text).append("iconCls", iconCls).append("state", state).append("checked", checked)
				.append("attributes", attributes);

		// 这里需要将children里的每个元素 toMap化
		if (children.size() == 0) {
			builder.append("children", new ArrayList<Map<String, Object>>());
		} else {
			final List<Map<String, Object>> childrenMapContainer = new ArrayList<Map<String, Object>>();
			for (EasyUITreeNode child : children) {
				childrenMapContainer.add(child.toMap());
			}
			builder.append("children", childrenMapContainer);
		}

		return builder.build();
	}

	/**
	 * 参见Mybatis中的MappedStatement
	 * @author LQ
	 *
	 */
	public static class Builder {
		private EasyUITreeNode easyUITreeNode = new EasyUITreeNode();

		public Builder(String id, String text) {
			easyUITreeNode.id = id;
			easyUITreeNode.text = text;

			easyUITreeNode.attributes = new HashMap<String, Object>();
			easyUITreeNode.children = new ArrayList<EasyUITreeNode>();
		}

		public Builder iconCls(String iconCls) {
			easyUITreeNode.iconCls = iconCls;
			return this;
		}

		public Builder state(String state) {
			easyUITreeNode.state = state;
			return this;
		}

		public Builder checked(boolean checked) {
			easyUITreeNode.checked = checked;
			return this;
		}

		public Builder addAttribute(String key, Object value) {
			easyUITreeNode.attributes.put(key, value);
			return this;
		}

		public EasyUITreeNode build() {
			assert null != easyUITreeNode.id;
			assert null != easyUITreeNode.text;

			return easyUITreeNode;
		}
	}

	@Override
	public boolean equals(Object other) {

		if (this == other) {
			return true;
		}

		if (other == null || other.getClass() != this.getClass()) {
			return false;
		}

		EasyUITreeNode that = (EasyUITreeNode) other;

		if (this.id.equalsIgnoreCase(that.id)) {
			return true;
		}

		//其它的比较交给父类
		return super.equals(other);
	}

	@Override
	public int hashCode() {

		return String.format("%s#%s", this.getClass().getName(), this.id).hashCode();

	}

	@Override
	public String toString() {
		final StringBuilder sb = new StringBuilder();
		sb.append("id : ");
		sb.append(id);
		sb.append(System.lineSeparator());

		sb.append("text : ");
		sb.append(text);
		sb.append(System.lineSeparator());

		sb.append("iconCls : ");
		sb.append(iconCls);
		sb.append(System.lineSeparator());

		sb.append("state : ");
		sb.append(state);
		sb.append(System.lineSeparator());

		sb.append("attributes : ");
		sb.append(attributes);
		sb.append(System.lineSeparator());

		sb.append("children : ");
		sb.append(children);
		sb.append(System.lineSeparator());

		return super.toString();
	}
}